/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package graphdisplay;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

/**
 *
 * @author Jimmy
 */
class ShortestPathGraphView extends JPanel implements DropTargetListener {

        boolean printShortesrtpath = false;
        java.util.List<Integer> path1;
        Graph<? extends Displayable> graph;
        List<? extends Displayable> path;
        List<Node> nodes1;
        private AbstractGraph<? extends Displayable>.Tree tree;
        DropTarget dt;
        JScrollPane scrollPane;

        public ShortestPathGraphView(Graph<? extends Displayable> graph, List<? extends Displayable> path) {
            this.graph = graph;
            this.path = path;
            dt = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
            //addNodesToGraph();
        }

        public ShortestPathGraphView(Graph<? extends Displayable> graph) {
            this.graph = graph;
            dt = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
        }

        public void setGraph(Graph<? extends Displayable> graph) {
            this.graph = graph;
        }
        
        public void setTree(AbstractGraph<? extends Displayable>.Tree tree) {
            this.tree = tree;
            repaint();
        }

        public void setTree1(boolean flag, java.util.List<Integer> path, List<Node> vertices) {
            path1 = path;
            nodes1 = vertices;
            printShortesrtpath = flag;
        }
        
        public void isShortestPathVisible(boolean flag){
            printShortesrtpath = flag;
        }

        public void setPath(List<? extends Displayable> path) {
            this.path = path;
            repaint();
        }
        
        public void setGraphViewScrollPane(JScrollPane pane){
            scrollPane = pane;
        }

        void addNodesToGraph() {
            removeAll();
            for (Node n : (List<Node>) graph.getVertices()) {
                add(n);
            }
            
            validate();
            //repaint();            
        }

        protected void paintComponent(java.awt.Graphics g) {
            super.paintComponent(g);

            // Draw vertices
            List<? extends Displayable> vertices = graph.getVertices();

            g.setColor(Color.BLACK);
            for (int i = 0; i < graph.getSize(); i++) {
                int x = vertices.get(i).getX();
                int y = vertices.get(i).getY();

                g.drawString(vertices.get(i).getName(), x - 12, y - 12);
            }
            g.setColor(Color.BLACK);

            // Draw edges
            for (int i = 0; i < graph.getSize(); i++) {
                List<Integer> neighbors = graph.getNeighbors(i);
                for (int j = 0; j < neighbors.size(); j++) {
                    int v = neighbors.get(j);
                    int x1 = graph.getVertex(i).getX() + 8;
                    int y1 = graph.getVertex(i).getY() + 8;
                    int x2 = graph.getVertex(v).getX() + 8;
                    int y2 = graph.getVertex(v).getY() + 8;

                    g.drawLine(x1, y1, x2, y2);
                }
            }

            // Display weights
            List<PriorityQueue<WeightedEdge>> queues = ((WeightedGraph<? extends Displayable>) graph).getWeightedEdges();

            g.setColor(Color.BLUE);
            for (int i = 0; i < graph.getSize(); i++) {
                ArrayList<WeightedEdge> list = new ArrayList<WeightedEdge>(queues.get(i));

                for (WeightedEdge edge : list) {                    
                    
                    int u = edge.u;
                    int v = edge.v;
                    double weight = edge.weight;
                    int x1 = graph.getVertex(u).getX();
                    int y1 = graph.getVertex(u).getY();
                    int x2 = graph.getVertex(v).getX();
                    int y2 = graph.getVertex(v).getY();
                    
                    g.drawString(weight + "", (x1 + x2) / 2, (y1 + y2) / 2 - 6);
                    
                }
            }
            g.setColor(Color.BLACK);
            
            if (printShortesrtpath) {
                /* if(tree ==null)
                {
                System.out.println("Done!");
                
                }*/
                if (path1 != null) {
                    g.setColor(java.awt.Color.RED);
                    for (int i = 0; i < path1.size() - 1; i++) {
                        //  int v = tree.getParent(i);
                        int x1 = nodes1.get(path1.get(i)).getX() + 8;
                        int y1 = nodes1.get(path1.get(i)).getY() + 8;
                        int x2 = nodes1.get(path1.get(i + 1)).getX() + 8;
                        int y2 = nodes1.get(path1.get(i + 1)).getY() + 8;

                        g.drawLine(x1, y1, x2, y2);
                    }

                }
            }
            // Highlight the edges in the spanning tree
            if (tree != null) {
                g.setColor(java.awt.Color.RED);
                for (int i = 0; i < tree.getNumberOfVerticesFound(); i++) {
                    if (tree.getParent(i) != -1) {
                        int v = tree.getParent(i);
                        int x1 = graph.getVertex(i).getX() + 8;
                        int y1 = graph.getVertex(i).getY() + 8;
                        int x2 = graph.getVertex(v).getX() + 8;
                        int y2 = graph.getVertex(v).getY() + 8;

                        g.drawLine(x1, y1, x2, y2);
                    }
                }
            }

            // Display the path
            if (path != null) {
                g.setColor(Color.RED);
                for (int i = 1; i < path.size(); i++) {
                    int x1 = path.get(i).getX() + 8;
                    int y1 = path.get(i).getY() + 8;
                    int x2 = path.get(i - 1).getX() + 8;
                    int y2 = path.get(i - 1).getY() + 8;
                    g.drawLine(x1, y1, x2, y2);
                }
            }
        }

        public void dragEnter(DropTargetDragEvent arg0) {
        }

        public void dragExit(DropTargetEvent arg0) {
        }

        public void dragOver(DropTargetDragEvent arg0) {
            Constant.x = arg0.getLocation().x;
            Constant.y = arg0.getLocation().y;
            repaint();
        }

        public void drop(DropTargetDropEvent arg0) {
        }

        public void dropActionChanged(DropTargetDragEvent arg0) {
        }

        public Dimension getPreferredSize() {
            return new Dimension(300, 500);
        }
    }
